package com.saohuobang.test.util;

import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Charsets;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.io.Files;
import com.saohuobang.test.model.BusinessInfo;
import com.saohuobang.test.model.UnitProperty;
import com.saohuobang.test.model.core.SystemException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.util.List;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * 作者 yaohua.liu
 * 日期 2015-12-15 18:08
 * 包名 com.saohuobang.test.service
 * 说明 ...
 */
public class PropertyUtil {

    private static final Logger logger = LoggerFactory.getLogger(PropertyUtil.class);

    /**
     * 检查 root directory path
     *
     * @param rootDirPath
     * @return file:the name is port
     * @throws SystemException
     */
    public static List<BusinessInfo> checkRootDirPath(String rootDirPath) throws SystemException {
        File dir = new File(rootDirPath);
        if (!dir.exists() || !dir.isDirectory()) {
            logger.error("properties root directory({}) not exists!", rootDirPath);
            throw new SystemException(-1, "properties root directory(" + rootDirPath + ") not exists!");
        }

        List<BusinessInfo> list = Lists.newArrayList();
        File[] businessDirs = dir.listFiles();
        if (businessDirs == null) {
            return list;
        }
        for (File file : businessDirs) {

            if (file == null || !file.isDirectory()) {// file 为空 或 不是文件夹
                continue;
            }
            String fileName = file.getName();
            logger.info("加载业务配置根目录:{}。（标准命名规则是${businessName}.${port}）", fileName);

            if (Strings.isNullOrEmpty(fileName) || !fileName.contains(".")) {// file name not contain .
                logger.error("业务目录（{}）必须包含.", fileName);
                continue;
            }
            int lastIndex = fileName.lastIndexOf('.');
            if (lastIndex == fileName.length()) {// . 位于最后
                continue;
            }
            String businessName = fileName.substring(0, lastIndex);// business name
            int port = 0;
            try {
                port = Integer.parseInt(fileName.substring(lastIndex + 1)); // port
            } catch (Exception e) {
                logger.error("busniess dir name:({}), must set port,eg 12306", file.getName());
                continue;
            }
            list.add(new BusinessInfo(businessName, file.getAbsolutePath(), port));
        }
        return list;
    }

    /**
     * 加载配置文件
     * @param businessInfos
     * @return
     */
    public static List<BusinessInfo> loadBusinessProperties(List<BusinessInfo> businessInfos) {
        checkNotNull(businessInfos, "Bussiness info can't null !");
        for (BusinessInfo businessInfo : businessInfos) {
            String rootDir = businessInfo.getRootDir();
            String propertiesPath = rootDir + "/properties.json";
            File propertiesFile = new File(propertiesPath);
            if (!propertiesFile.exists() || !propertiesFile.isFile()) {
                logger.warn("properties file not exist or not a file:{}", propertiesPath);
                continue;
            }
            String dataDirPath = rootDir + "/data";
            File dataFile = new File(dataDirPath);
            if (!dataFile.exists() || !dataFile.isDirectory()) {
                logger.warn("data directory not exist or not a directory:{}", dataDirPath);
                continue;
            }
            String jsonData = null;
            try {
                jsonData = Files.toString(propertiesFile, Charsets.UTF_8);
            } catch (IOException e) {
                logger.error("had a exception while read content from {},msg={}", propertiesPath, e.getMessage(), e);
                continue;
            }
            if (Strings.isNullOrEmpty(jsonData)) {
                continue;
            }
            List<UnitProperty> properties = JSONObject.parseArray(jsonData, UnitProperty.class);
            if (properties != null && properties.size() > 0) {
                businessInfo.setProperties(properties);
            }
        }
        return businessInfos;
    }

    /**
     * 把root dir & businessInfos to List<String>
     * @param rootDir
     * @param businessInfos
     * @return
     */
    public static List<String> businessToString(String rootDir, List<BusinessInfo> businessInfos){
        List<String> result = Lists.newArrayList();
        if(!Strings.isNullOrEmpty(rootDir)){
            result.add(rootDir);
        }
        if(businessInfos == null || businessInfos.size() == 0){
            return result;
        }
        for(BusinessInfo info: businessInfos){
            if(info == null || Strings.isNullOrEmpty(info.getRootDir())){
                continue;
            }
            result.add(info.getRootDir()+"/data");
        }
        return result;
    }

    private static String[] fileTypes = {".html", ".json", ".text", ".xml"};

    /**
     * 检查是否是数据查配置文件
     *
     * @param fileName
     * @return
     */
    public static boolean checkFileType(String fileName) {
        if (Strings.isNullOrEmpty(fileName)) {
            return false;
        }

        for (String item : fileTypes) {
            if (fileName.endsWith(item)) {
                return true;
            }
        }

        return false;
    }

    /**
     * 检查是否是新建业务目录
     *
     * @param fileName
     * @return
     */
    public static boolean checkBusinessRootDir(String fileName) {
        if (!fileName.contains(".")) {
            return false;
        }
        int lastIndex = fileName.lastIndexOf('.');
        if (lastIndex == fileName.length()) {// . 位于最后
            return false;
        }
        String businessName = fileName.substring(0, lastIndex);// business name
        int port = 0;
        try {
            port = Integer.parseInt(fileName.substring(lastIndex + 1)); // port
        } catch (Exception e) {
            return false;
        }
        logger.info("新建业务配置信息，业务名：{},端口：{}", businessName, port);
        return true;
    }

}
